using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 主要为2D音效播放
/// 背景音乐仅限于2D
/// </summary>
public class 音效控制器 : 单例_基础可挂载自动管理器<音效控制器>
{

    private float _背景音量 = 1;
    private float _音效音量 = 1;
    public int 二维音频源上限 = 16;

    public float 全局背景音量 => _背景音量;
    public float 全局音效音量 => _音效音量;

    #region 2D音效管理

    public bool 背景音乐是否正在播放 => 背景音乐音频源.isPlaying;

    private AudioSource 背景音乐音频源;

    private List<AudioSource> 音效音频源 = new List<AudioSource>();

    private AudioSource 添加音效音频源(bool 循环=false)
    {
        AudioSource 音频源 = gameObject.AddComponent<AudioSource>();
        音频源.loop = 循环;
        音效音频源.Add(音频源);
        return 音频源;
    }

    private AudioSource 找到空闲的音效音频源()
    {
        foreach (var item in 音效音频源)
            if (!item.isPlaying)
                return item;
        return 添加音效音频源();
    }

    public void 清除过多的2D音效音频源()
    {
        int ls = 0;
        List<AudioSource> 空闲音频源 = new List<AudioSource>();
        foreach (var item in 音效音频源)
        {
            if (!item.isPlaying)
            {
                空闲音频源.Add(item);
                ls++;
            }
        }
        int 音效音频源数量 = 音效音频源.Count;
        if (音效音频源数量 > 二维音频源上限)
        {
            int 正在使用音频源 = 音效音频源数量 - ls;
            if(正在使用音频源< 音效音频源数量)
            {
                //清除多余的音频源
                int 移除数量 = 音效音频源数量 - 正在使用音频源;
                for (int i = 0; i < 移除数量; i++)
                {
                    if (空闲音频源.Count > 0)
                    {
                        AudioSource 处理 = 空闲音频源[0];
                        空闲音频源.Remove(处理);
                        音效音频源.Remove(处理);
                        Destroy(处理);
                    }
                }
            }
            else
            {
                while (空闲音频源.Count>0)
                {
                    AudioSource 处理 = 空闲音频源[0];
                    空闲音频源.Remove(处理);
                    音效音频源.Remove(处理);
                    Destroy(处理);
                }
            }
        }
    }

    public void 播放背景音乐() => 背景音乐音频源.Play();

    public void 暂停背景音乐() => 背景音乐音频源.Pause();

    public void 设置背景音量(float 音量)
    {
        _背景音量 = 音量;
        背景音乐音频源.volume = _背景音量;
    }

    public void 切换背景音乐(AudioClip 音频)
    {
        if (背景音乐音频源 == null)
        {
            背景音乐音频源 = gameObject.AddComponent<AudioSource>();
            背景音乐音频源.loop = true;
        }
        背景音乐音频源.clip = 音频;
        背景音乐音频源.volume = _背景音量;
        背景音乐音频源.Play();
    }
    /// <summary>
    /// 异步加载
    /// </summary>
    /// <param name="音频名"></param>
    public void 切换背景音乐(string 音频名)=>资源管理器.获取实例.加载_异步<AudioClip>($"音频/背景音乐/{音频名}", 切换背景音乐);

    public void 播放2D音效(AudioClip 音频)
    {
        AudioSource 音频源 = 找到空闲的音效音频源();
        音频源.clip = 音频;
        音频源.volume = _音效音量;
        音频源.Play();
    }
    public void 播放2D音效(string 音频名称) => 资源管理器.获取实例.加载_异步<AudioClip>($"音频/音效/{音频名称}", 播放2D音效);

    /// <summary>
    /// 全局音效
    /// </summary>
    public void 恢复全局音效播放()
    {
        foreach (var item in 音效音频源)
        {
            if(item.time!=0)
                item.Play();
        }

        foreach (var item in 三维音频源管理.Keys)
            三维音频源管理[item].恢复音效音频源();
    }
    public void 暂停全局音效()
    {
        foreach (var item in 音效音频源)
            item.Pause();

        foreach (var item in 三维音频源管理.Keys)
            三维音频源管理[item].暂停音效音频源();
    }
    #endregion

    /// <summary>
    /// 将改变全局音量
    /// </summary>
    /// <param name="音量"></param>
    public void 设置全局音效音量(float 音量)
    {
        _音效音量 = 音量;
        foreach (var item in 音效音频源)
            item.volume = _音效音量;
        foreach (var item in 三维音频源管理.Keys)
            三维音频源管理[item].设置音量();
    }


    //3D 比较特殊 需要有位置属性
    //音频源需要在对象身上

    //3D音效分 音效和循环播放

    Dictionary<GameObject, 音频管理> 三维音频源管理 = new Dictionary<GameObject, 音频管理>();

    public void 播放3D音效(GameObject 对象,AudioClip 音频)
    {
        if (!三维音频源管理.ContainsKey(对象))
            三维音频源管理.Add(对象, new 音频管理(对象));
        音频管理 管理 = 三维音频源管理[对象];
        管理.播放音效(音频);
    }
    public void 播放3D音效(GameObject 对象, string 音频名称) => 资源管理器.获取实例.加载_异步<AudioClip>(音频名称, (clip) => 播放3D音效(对象, clip));


    public void 播放3D循环音效(GameObject 对象,AudioClip 音频)
    {
        if (!三维音频源管理.ContainsKey(对象))
            三维音频源管理.Add(对象, new 音频管理(对象));

        音频管理 管理 = 三维音频源管理[对象];
        管理.设置循环音频源(音频);
    }

    public void 播放3D循环音效(GameObject 对象, string 音频名称) => 资源管理器.获取实例.加载_异步<AudioClip>(音频名称, (clip) => 播放3D循环音效(对象, clip));

    public void 暂停3D循环音效(GameObject 对象)
    {
        if (!三维音频源管理.ContainsKey(对象))
            return;

        三维音频源管理[对象].暂停循环音频源();
    }

    public void 恢复3D循环音效(GameObject 对象)
    {
        if (!三维音频源管理.ContainsKey(对象))
            return;

        三维音频源管理[对象].恢复循环音频源();
    }

    public void 清除3D循环音效(GameObject 对象)
    {
        if (!三维音频源管理.ContainsKey(对象))
            return;
        三维音频源管理[对象].清除循环音频源();
    }


    class 音频管理
    {
        public List<AudioSource> 音频源 = new List<AudioSource>();
        public List<AudioSource> 循环音频源 = new List<AudioSource>();//注意该集合不能移除指定的音频源
        public GameObject 对象;

        public void 设置音量()
        {
            foreach (var item in 音频源)
                item.volume = 音效控制器.获取实例.全局音效音量;
            foreach (var item in 循环音频源)
                item.volume = 音效控制器.获取实例.全局音效音量;
        }

        public 音频管理(GameObject 对象) => this.对象 = 对象;
        public void 播放音效(AudioClip 音频)
        {
            AudioSource ls = 找到空闲的音效音频源();
            ls.clip = 音频;
            ls.volume = 音效控制器.获取实例.全局音效音量;
            ls.Play();
        }
        private AudioSource 找到空闲的音效音频源()
        {
            foreach (var item in 音频源)
                if (!item.isPlaying)
                    return item;
            AudioSource ls = 对象.AddComponent<AudioSource>();
            ls.spatialBlend = 1; //改为3D音频源
            ls.volume = 音效控制器.获取实例.全局音效音量;
            音频源.Add(ls);
            return ls;
        }

        /// <summary>
        /// 注意 循环音频源 只能更改音频 不能找到空闲的音频源
        /// </summary>
        /// <returns></returns>
        public AudioSource 添加循环音频源()
        {
            AudioSource 返回值 = 对象.AddComponent<AudioSource>();
            返回值.spatialBlend = 1;
            返回值.loop = true;
            返回值.volume = 音效控制器.获取实例.全局音效音量;
            循环音频源.Add(返回值);
            return 返回值;
        }

        public void 清除循环音频源()
        {
            foreach (var item in 循环音频源)
                Destroy(item);
            循环音频源 = new List<AudioSource>();
        }

        public void 暂停循环音频源()
        {
            foreach (var item in 循环音频源)
                item.Pause();
        }

        public void 恢复循环音频源()
        {
            foreach (var item in 循环音频源)
                item.Play();
        }

        public void 设置循环音频源(AudioClip 音频,int 序号 = 0)
        {
            if (循环音频源.Count == 0)
                添加循环音频源();
            if (循环音频源.Count <= 序号)
            {
                Debug.LogError("设置了不存在的3D循环音频源");
                return;
            }
            循环音频源[序号].clip = 音频;
            循环音频源[序号].Play();
        }

        public void 暂停音效音频源()
        {
            foreach (var item in 循环音频源)
                item.Pause();
        }
        public void 恢复音效音频源()
        {
            foreach (var item in 循环音频源)
            {
                if(item.time!=0)//防止激活休眠的音频源
                    item.Play();
            }
        }
    }
}
